package com.unlcn.ils.wms.backend.service.inbound.impl;

import cn.huiyunche.commons.exception.BusinessException;
import cn.huiyunche.commons.utils.HttpRequestUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.unlcn.ils.wms.backend.bo.inboundBO.WmsAllocationBO;
import com.unlcn.ils.wms.backend.bo.inboundBO.WmsInboundAllocationBO;
import com.unlcn.ils.wms.backend.bo.inboundBO.WmsInboundOrderBO;
import com.unlcn.ils.wms.backend.enums.*;
import com.unlcn.ils.wms.backend.service.baseData.WmsLocationService;
import com.unlcn.ils.wms.backend.service.inbound.WmsStrategyService;
import com.unlcn.ils.wms.base.businessDTO.baseData.WmsEmptyLocationDTO;
import com.unlcn.ils.wms.base.businessDTO.inbound.AsnOrderDTO;
import com.unlcn.ils.wms.base.businessDTO.inbound.AsnOrderDetailDTO;
import com.unlcn.ils.wms.base.mapper.additional.*;
import com.unlcn.ils.wms.base.mapper.additional.wmsInboundPloy.*;
import com.unlcn.ils.wms.base.mapper.inbound.WmsInboundAllocationMapper;
import com.unlcn.ils.wms.base.mapper.inbound.WmsInboundOrderDetailMapper;
import com.unlcn.ils.wms.base.mapper.inbound.WmsInboundOrderMapper;
import com.unlcn.ils.wms.base.mapper.inbound.WmsTmsLogMapper;
import com.unlcn.ils.wms.base.mapper.stock.WmsLocationMapper;
import com.unlcn.ils.wms.base.mapper.stock.WmsVehicleContrastMapper;
import com.unlcn.ils.wms.base.mapper.stock.WmsWarehouseMapper;
import com.unlcn.ils.wms.base.mapper.sys.SysUserMapper;
import com.unlcn.ils.wms.base.mapper.sys.SysUserRoleMapper;
import com.unlcn.ils.wms.base.mapper.sys.WmsCardMapper;
import com.unlcn.ils.wms.base.model.inbound.*;
import com.unlcn.ils.wms.base.model.stock.*;
import com.unlcn.ils.wms.base.model.sys.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 策略service
 * Created by DELL on 2017/8/8.
 */
@Service
public class WmsStrategyServiceImpl implements WmsStrategyService {
    private Logger LOGGER = LoggerFactory.getLogger(WmsStrategyServiceImpl.class);

    private static final String INBOUND_QUALITY = "1", INBOUND_EXCP = "2";//1正常入库;2异常入库

    @Value("${tms.pickup.host.url}")
    private String propertyUrl;

    @Value("${tms.pickup.host.timeout}")
    private String propertyTime;

    @Value("${tms.encode.key}")
    private String propertyKey;

    @Autowired
    private WmsInboundAllocationMapper wmsInboundAllocMapper;

    @Autowired
    private WmsInboundOrderMapper wmsInboundOrderMapper;

    @Autowired
    private WmsLocationExtMapper wmsLocationExtMapper;

    @Autowired
    private WmsAllocationExtMapper wmsAllocationExtMapper;

    @Autowired
    private WmsInventoryLocationExtMapper wmsInventoryLocationExtMapper;

    @Autowired
    private WmsInboundOrderDetailMapper wmsInboundOrderDetailMapper;

    @Autowired
    private WmsInboundAsnOrderAddMapper wmsInboundAsnOrderAddMapper;

    @Autowired
    private WmsInboundPloyExtMapper wmsInboundPloyExtMapper;

    @Autowired
    private WmsInboundPloyConditionExtMapper wmsInboundPloyConditionExtMapper;

    @Autowired
    private WmsInboundPloyOperatorExtMapper wmsInboundPloyOperatorExtMapper;

    @Autowired
    private WmsInboundPloyFlowtoExtMapper wmsInboundPloyFlowtoExtMapper;

    @Autowired
    private WmsInboundPloyLocationExtMapper wmsInboundPloyLocationExtMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private WmsWarehouseMapper wmsWarehouseMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private WmsVehicleContrastMapper vehicleContrastMapper;

    @Autowired
    private WmsLocationMapper wmsLocationMapper;

    @Autowired
    private WmsCardMapper wmsCardMapper;

    private WmsTmsLogMapper wmsTmsLogMapper;

    private WmsLocationService wmsLocationService;

    @Autowired
    public void setWmsTmsLogMapper(WmsTmsLogMapper wmsTmsLogMapper) {
        this.wmsTmsLogMapper = wmsTmsLogMapper;
    }

    @Autowired
    public void setWmsLocationService(WmsLocationService wmsLocationService) {
        this.wmsLocationService = wmsLocationService;
    }

    @Override
    public synchronized String addAllocation(WmsInboundAllocationBO wmsInboundAllocationBO) throws Exception {
        int result = 0;
        try {
            //效验库位是否已经被占用
            List<String> targetZoneIdList = Lists.newArrayList();
            List<String> targetLocationList = Lists.newArrayList();
            targetZoneIdList.add(wmsInboundAllocationBO.getAlTargetZoneCode());
            targetLocationList.add(wmsInboundAllocationBO.getAlTargetLocCode());
            Map<String, Object> paramMap = Maps.newHashMap();
            paramMap.put("targetZoneCode", targetZoneIdList);
            paramMap.put("targetLocationCode", targetLocationList);
            //int count = wmsLocationExtMapper.getInfoByZoneIdAndLocationId(paramMap);
            //用已经选择的库位区库位,直接去空库位视图表查询,当不能能查到东西
            //或者去库存的从表库存库位表查询，当能查到东西
            //即为空库位，这里查的是库存库位表 返回一个LIST 将已用的库位返回给前端
            List<WmsInventoryLocation> wmsInventoryLocations = wmsInventoryLocationExtMapper.selectInfoByLocation(paramMap);
            if (wmsInventoryLocations != null && wmsInventoryLocations.size() > 0) {
                StringBuffer locStr = new StringBuffer();
                for (WmsInventoryLocation wmsInventoryLocation : wmsInventoryLocations) {
                    locStr.append(wmsInventoryLocation.getInvlocZoneName())
                            .append(":")
                            .append(wmsInventoryLocation.getInvlocLocName())
                            .append(";");
                }
                return locStr.toString();
            }

            WmsInboundAllocation wmsInboundAlloc = new WmsInboundAllocation();
            wmsInboundAlloc.setAlOdId(wmsInboundAllocationBO.getAlOdId());//运单ID
            //wmsInboundAlloc.setAlCustomerCode(wmsAllocationBO.get());//货主
            wmsInboundAlloc.setAlWaybillNo(wmsInboundAllocationBO.getAlWaybillNo());//单据号
            wmsInboundAlloc.setAlVehicleSpecCode(wmsInboundAllocationBO.getAlVehicleSpecCode());//车型
            wmsInboundAlloc.setAlVin(wmsInboundAllocationBO.getAlVin());//底盘号
            wmsInboundAlloc.setAlSourceZoneId(wmsInboundAllocationBO.getAlSourceZoneId());//库区ID
            wmsInboundAlloc.setAlSourceZoneCode(wmsInboundAllocationBO.getAlSourceZoneCode());//目的库区
            wmsInboundAlloc.setAlSourceZoneName(wmsInboundAllocationBO.getAlSourceZoneName());//目的库区
            wmsInboundAlloc.setAlSourceLocId(wmsInboundAllocationBO.getAlSourceLocId());//库位ID
            wmsInboundAlloc.setAlSourceLocCode(wmsInboundAllocationBO.getAlSourceLocCode());//目的库位
            wmsInboundAlloc.setAlSourceLocName(wmsInboundAllocationBO.getAlSourceLocName());//目的库位
            wmsInboundAlloc.setAlStatus(String.valueOf(WmsInboundStatusEnum.WMS_INBOUND_WAIT_INBOUND.getValue()));
            //wmsInboundAlloc.setAlType(allocType);//10:人工分配；20：自动分配 需要前端判断当我返回了库区库位即为自动分配，否则人工分配
            result = wmsInboundAllocMapper.insert(wmsInboundAlloc);
            //分配之后修改运单状态为已分配，已分配的状态还能进行人工修改
            WmsInboundOrder wmsInboundAsnOrder = wmsInboundOrderMapper.selectByPrimaryKey(Long.valueOf(wmsInboundAllocationBO.getAlOdId()));
            wmsInboundAsnOrder.setOdStatus(String.valueOf(WmsInboundStatusEnum.WMS_INBOUND_WAIT_INBOUND.getValue()));
            result = wmsInboundOrderMapper.updateByPrimaryKey(wmsInboundAsnOrder);
            WmsInboundOrderDetail wmsInboundOrderDetail = new WmsInboundOrderDetail();
            wmsInboundOrderDetail.setOddOdId(wmsInboundAsnOrder.getOdId());
            wmsInboundOrderDetail.setOddWhZoneCode(wmsInboundAllocationBO.getAlSourceZoneCode());
            wmsInboundOrderDetail.setOddWhZoneName(wmsInboundAllocationBO.getAlSourceZoneCode());// name先用code
            wmsInboundOrderDetail.setOddWhLocCode(wmsInboundAllocationBO.getAlSourceLocCode());
            wmsInboundOrderDetail.setOddWhLocName(wmsInboundAllocationBO.getAlSourceLocCode());// name先用code
            wmsInboundAsnOrderAddMapper.updateOrderDetailByPrimaryKeySelective(wmsInboundOrderDetail);

        } catch (Exception ex) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new Exception("数据库异常");
        }
        return "";
    }


    @Override
    public synchronized List<WmsAllocationBO> updateAutoAllocation(List<WmsAllocationBO> wmsAllocationVOList,
                                                                   String whCode) throws Exception {
        List<WmsInboundPloy> wmsInboundPloyList = wmsInboundPloyExtMapper.getPloyList(whCode);
        //查询所有空库位
        Map<String, Object> queryMap = Maps.newHashMap();
        Map<String, List<WmsEmptyLocationDTO>> zoneMap = Maps.newHashMap();//根据库区维度进行存放

        //需要传当前仓库的code

        //queryMap.put("whCode","001");
        List<com.unlcn.ils.wms.base.businessDTO.baseData.WmsEmptyLocationDTO> locationList = wmsLocationExtMapper.getWmsEmptyLocation(queryMap);
        if (CollectionUtils.isEmpty(locationList)) {
            return null;
        }
        if (CollectionUtils.isEmpty(wmsInboundPloyList)) {
            for (WmsAllocationBO wmsAllocationBO : wmsAllocationVOList) {
                wmsAllocationBO.setAlTargetZoneCode(locationList.get(0).getLocZoneCode());
                wmsAllocationBO.setAlTargetZoneName(locationList.get(0).getLocZoneName());
                wmsAllocationBO.setAlTargetLocCode(locationList.get(0).getLocCode());
                wmsAllocationBO.setAlTargetLocName(locationList.get(0).getLocName());
            }
            return wmsAllocationVOList;
        }
        //根据策略code查询策略条件
        Map<String, String> resultLocationMap = Maps.newHashMap();

        for (WmsEmptyLocationDTO wmsEmptyLocationDTO : locationList) {
            if (zoneMap.containsKey(wmsEmptyLocationDTO.getLocZoneCode())) {
                List<WmsEmptyLocationDTO> zlist = zoneMap.get(wmsEmptyLocationDTO.getLocZoneCode());
                zlist.add(wmsEmptyLocationDTO);
                zoneMap.put(wmsEmptyLocationDTO.getLocZoneCode(), zlist);
            } else {
                List<WmsEmptyLocationDTO> userList = Lists.newArrayList();
                userList.add(wmsEmptyLocationDTO);
                zoneMap.put(wmsEmptyLocationDTO.getLocZoneCode(), userList);
            }
        }

        /*Map<String,Map<String,Map<String,Object>>> map = Maps.newConcurrentMap();//所有策略信息
        Map<String,Object> conditionMap = Maps.newConcurrentMap();//条件
        Map<String,Object> flowtoMap = Maps.newConcurrentMap();//流向
        Map<Long,Object> locationMap = Maps.newConcurrentMap();//库区库位*/

        //查询库区库位

        Map<String, List<WmsEmptyLocationDTO>> havaLocation = Maps.newHashMap();//得到空库位
        List<WmsInboundPloyLocation> wmsInboundPloyLocationList = wmsInboundPloyLocationExtMapper.getPloyLocationList(wmsInboundPloyList.get(0).getPyCode());
        for (WmsInboundPloyLocation wmsInboundPloyLocation : wmsInboundPloyLocationList) {
            String startRow = wmsInboundPloyLocation.getPylStartRow();//开始排
            String endRow = wmsInboundPloyLocation.getPylEndRow();//结束排
            List<WmsEmptyLocationDTO> list = zoneMap.get(wmsInboundPloyLocation.getPylZoneCode());//根据策略库区得到空库位
            List<WmsEmptyLocationDTO> getLocationListStr = getLoationList(list, Long.valueOf(startRow), Long.valueOf(endRow));
            havaLocation.put(wmsInboundPloyLocation.getPylZoneCode(), getLocationListStr);
        }

        //已经被占用的库位，在第二次循环的时候需要去掉此list的库位。

        List<String> occupyList = Lists.newArrayList();


        //循环被自动分配的订单

        for (WmsAllocationBO wmsAllocationBO : wmsAllocationVOList) {
            String customerCode = wmsAllocationBO.getAlCustomerCode();//货主
            String vehicleSpecCode = wmsAllocationBO.getAlVehicleSpecCode();//车型
            WmsInboundOrder wmsInboundOrder = wmsInboundOrderMapper.selectByPrimaryKey(Long.valueOf(wmsAllocationBO.getAlOdId()));
            if (null == wmsInboundOrder) {
                Exception ex = new Exception("订单信息为空");
                throw ex;
            }
            String dest = wmsInboundOrder.getOdDest();//目的地
            String origin = wmsInboundOrder.getOdOrigin();//起始地

            //订单能匹配上当前选择的策略，当订单匹配策略那么返回havaLocation里的库位，否则不返回让前端自己人工选择。

            boolean inPloy = true;


            //查询条件

            List<WmsInboundPloyCondition> wmsInboundPloyConditionList = wmsInboundPloyConditionExtMapper.getPloyConditionList(wmsInboundPloyList.get(0).getPyCode());
            for (WmsInboundPloyCondition wmsInboundPloyCondition : wmsInboundPloyConditionList) {
                List<WmsInboundPloyOperator> wmsInboundPloyOperator = wmsInboundPloyOperatorExtMapper.getOperatorByCode(wmsInboundPloyCondition.getPycOperatorCode());
                String operatorCode = wmsInboundPloyOperator.get(0).getPyoOperatorCode();
                String[] value = wmsInboundPloyCondition.getPycValue().split("&");

                if ("10".equals(wmsInboundPloyCondition.getPycType())) {//货主
                    boolean flag = Arrays.asList(value).contains(customerCode);

                    //10为货主，判断订单是否适用于当前策略 ，不适用直接退出循环 库区库位赋值为空

                    if (!isPloy(operatorCode, flag)) {
                        wmsAllocationBO.setAlTargetZoneCode("");
                        wmsAllocationBO.setAlTargetZoneName("");
                        wmsAllocationBO.setAlTargetLocCode("");
                        wmsAllocationBO.setAlTargetLocName("");
                        break;
                    }
                }
                if ("20".equals(wmsInboundPloyCondition.getPycType())) {//车型

                    //20为车型，判断订单是否适用于当前策略 ，不适用直接退出循环 库区库位赋值为空

                    if (!isPloy(operatorCode, Arrays.asList(value).contains(vehicleSpecCode))) {
                        wmsAllocationBO.setAlTargetZoneCode("");
                        wmsAllocationBO.setAlTargetZoneName("");
                        wmsAllocationBO.setAlTargetLocCode("");
                        wmsAllocationBO.setAlTargetLocName("");
                        break;
                    }
                }

                //conditionMap.put(wmsInboundPloyCondition.getPycCode(), wmsInboundPloyCondition);
            }


            //查询流向

            List<WmsInboundPloyFlowto> wmsInboundPloyFlowtoList = wmsInboundPloyFlowtoExtMapper.getPloyFlowtoList(wmsInboundPloyList.get(0).getPyCode());
            for (WmsInboundPloyFlowto wmsInboundPloyFlowto : wmsInboundPloyFlowtoList) {
                if (wmsInboundPloyFlowto.getPyfFromCode().equals(origin) && wmsInboundPloyFlowto.getPyfToCode().equals(dest)) {
                    inPloy = true;
                }
            }

            for (Map.Entry<String, List<WmsEmptyLocationDTO>> entry : havaLocation.entrySet()) {
                List<WmsEmptyLocationDTO> valueList = entry.getValue();
                if (CollectionUtils.isEmpty(valueList)) {
                    break;
                }
                wmsAllocationBO.setAlTargetZoneCode(entry.getKey());//code跟name一样
                wmsAllocationBO.setAlTargetZoneName(entry.getKey());//code跟name一样
                for (WmsEmptyLocationDTO list : valueList) {
                    wmsAllocationBO.setAlTargetLocCode(list.getLocCode());
                    wmsAllocationBO.setAlTargetLocName(list.getLocName());
                    occupyList.add(list.getLocCode());
                    valueList.remove(list);
                    break;
                }
            }

            //当策略没有匹配到库位那么任务分配一个库区库位

            if (wmsAllocationBO.getAlTargetZoneCode().isEmpty()
                    || wmsAllocationBO.getAlTargetZoneName().isEmpty()
                    || wmsAllocationBO.getAlTargetLocCode().isEmpty()
                    || wmsAllocationBO.getAlTargetLocName().isEmpty()) {
                wmsAllocationBO.setAlTargetZoneCode(locationList.get(0).getLocZoneCode());
                wmsAllocationBO.setAlTargetZoneName(locationList.get(0).getLocZoneName());
                wmsAllocationBO.setAlTargetLocCode(locationList.get(0).getLocCode());
                wmsAllocationBO.setAlTargetLocName(locationList.get(0).getLocName());
            }
        }
        return wmsAllocationVOList;
    }

    /**
     * 判断订单是否适用于当前选择的策略
     * 是 true
     * 否 false
     */
    private boolean isPloy(String operatorCode, boolean flag) {
        boolean isPloy = false;
        switch (operatorCode) {
            case "10"://等于
                if (flag) {
                    isPloy = true;
                }
                break;
            case "20"://不等于
                isPloy = !flag;
                break;
            case "30"://包含
                if (flag) {
                    isPloy = true;
                }
                break;
            case "40"://不包含
                isPloy = !flag;
                break;
            case "50"://是
                if (flag) {
                    isPloy = true;
                }
                break;
            case "60"://不是
                isPloy = !flag;
                break;
            case "70"://大于等于
                break;
            case "80"://小于等于
                break;
        }
        return isPloy;
    }

    /**
     * 根据条件返回所需策略库位
     */
    private List<WmsEmptyLocationDTO> getLoationList(List<WmsEmptyLocationDTO> list, Long startRow, Long endRow) {
        List<WmsEmptyLocationDTO> locationList = Lists.newArrayList();
        for (WmsEmptyLocationDTO wmsEmptyLocationDTO : list) {
            String column = wmsEmptyLocationDTO.getLocName().substring(wmsEmptyLocationDTO.getLocName().indexOf("-") + 1, wmsEmptyLocationDTO.getLocName().lastIndexOf("-"));
            Long row = Long.valueOf(column);
            if (row >= startRow && row <= endRow) {
                locationList.add(wmsEmptyLocationDTO);
            }
        }
        return locationList;
    }


    @Override
    public boolean updateToConfirmAllocation(List<WmsInboundOrderBO> wmsAllocationVOList) {
        int result = 0;
        for (WmsInboundOrderBO wmsInboundOrderBO : wmsAllocationVOList) {
            //分配确认之后修改运单状态为待入库，确认分配的状态不能再进行分配。需要修改库区库位需要去库区概括修改。
            WmsInboundOrder wmsInboundOrder = wmsInboundOrderMapper.selectByPrimaryKey(wmsInboundOrderBO.getOdId());
            wmsInboundOrder.setOdStatus(String.valueOf(WmsStatusEnum.WMS_INBOUND_WAIT_INBOUND.getValue()));
            result = wmsInboundOrderMapper.updateByPrimaryKey(wmsInboundOrder);
            Map<String, Object> paramMap = Maps.newHashMap();
            paramMap.put("alStatus", String.valueOf(WmsStatusEnum.WMS_INBOUND_WAIT_INBOUND.getValue()));
            paramMap.put("alOdId", String.valueOf(wmsInboundOrderBO.getOdId()));
            wmsAllocationExtMapper.updateStatusByAsnOrderId(paramMap);
        }
        return result > 0;
    }


    private WmsInboundAllocationExtMapper wmsInboundAllocationExtMapper;

    @Autowired
    public void setWmsInboundAllocationExtMapper(WmsInboundAllocationExtMapper wmsInboundAllocationExtMapper) {
        this.wmsInboundAllocationExtMapper = wmsInboundAllocationExtMapper;
    }

    @Override
    public AsnOrderDTO saveAllcationByExtra(String vin, String userId_str) throws Exception {
        LOGGER.info("WmsStrategyServiceImpl.saveAllcationByExtra vin: {}, userId: {}", vin, userId_str);
        //因为分为手动输入和扫码输入;需要根据长度判断是否输入的车架号
        AsnOrderDTO asnOrderDTO;
        if (StringUtils.isBlank(vin)) {
            throw new BusinessException("输入信息不能为空!");
        }
        if (StringUtils.isBlank(userId_str)) {
            throw new BusinessException("用户ID不能为空!");
        }
        int userId = Integer.parseInt(userId_str);

        String locSize = null;
        //车型id
        Long odStyleId = null;
        //判断手动输入的是车架号还是运单号
        if (vin.trim().length() != 17) {
            //车架号实际是运单号(只是参数名为vin)
            WmsInboundOrderExample orderExample = new WmsInboundOrderExample();
            WmsInboundOrderExample.Criteria criteria = orderExample.createCriteria();
            criteria.andOdWaybillNoEqualTo(vin);
            criteria.andIsDeletedNotEqualTo(DeleteFlagEnum.DELETED.getValue());
            List<WmsInboundOrder> wmsInboundOrders = wmsInboundOrderMapper.selectByExample(orderExample);
            if (CollectionUtils.isEmpty(wmsInboundOrders)) {
                throw new BusinessException("未查询到对应的运单号的入库信息");
            }

            WmsInboundOrder wmsInboundOrder = wmsInboundOrders.get(0);
            if (Objects.equals(wmsInboundOrder.getInspectStatus(), TmsInspectStatusEnum.WAYBILL_INIT.getValue())) {
                throw new BusinessException("该车辆还未进行验车!");
            }
            if (Objects.equals(wmsInboundOrder.getInspectStatus(), TmsInspectStatusEnum.WAYBILL_EXCP.getValue())) {
                throw new BusinessException("该车辆还未进行验车登记");
            }
            if (Objects.equals(wmsInboundOrder.getOdCheckResult(), null)) {
                throw new BusinessException("该车辆还未进行移车申请!");
            }

            //查出运单号对应的车架号
            Long odId = wmsInboundOrders.get(0).getOdId();
            WmsInboundOrderDetailExample detailExample = new WmsInboundOrderDetailExample();
            WmsInboundOrderDetailExample.Criteria detailExampleCriteria = detailExample.createCriteria();
            detailExampleCriteria.andOddOdIdEqualTo(odId);
            List<WmsInboundOrderDetail> wmsInboundOrderDetails = wmsInboundOrderDetailMapper.selectByExample(detailExample);
            if (CollectionUtils.isEmpty(wmsInboundOrderDetails)) {
                throw new BusinessException("未查询到对应的运单号的车架号信息");
            }
            vin = wmsInboundOrderDetails.get(0).getOddVin();

            //获取车型id
            odStyleId = wmsInboundOrder.getOdStyleId();

        } else {
            WmsInboundOrderDetailExample detailExample = new WmsInboundOrderDetailExample();
            detailExample.setOrderByClause(" odd_id desc ");
            detailExample.createCriteria().andOddVinEqualTo(vin);
            List<WmsInboundOrderDetail> wmsInboundOrderDetails = wmsInboundOrderDetailMapper.selectByExample(detailExample);
            if (CollectionUtils.isNotEmpty(wmsInboundOrderDetails)) {
                WmsInboundOrderExample orderExample = new WmsInboundOrderExample();
                orderExample.createCriteria().andOdIdEqualTo(wmsInboundOrderDetails.get(0).getOddOdId());
                List<WmsInboundOrder> inboundOrderList = wmsInboundOrderMapper.selectByExample(orderExample);
                if (CollectionUtils.isNotEmpty(inboundOrderList)) {
                    WmsInboundOrder order = inboundOrderList.get(0);
                    if (order != null) {
                        odStyleId = order.getOdStyleId();
                    }
                }
            }
        }
        //获取车型
        if (odStyleId != null) {
            WmsVehicleContrastExample vehicleContrastExample = new WmsVehicleContrastExample();
            vehicleContrastExample.createCriteria().andVcCodeEqualTo(odStyleId);
            List<WmsVehicleContrast> contrastList = vehicleContrastMapper.selectByExample(vehicleContrastExample);
            if (CollectionUtils.isNotEmpty(contrastList)) {
                locSize = contrastList.get(0).getVcSize();
                if (StringUtils.isBlank(locSize)) {
                    throw new BusinessException("当前车辆类型数据异常, 请核实");
                }
            }
        }


        //通过vin得到入库基本信息

        asnOrderDTO = wmsInboundAsnOrderAddMapper.queryByVin(vin);
        if (Objects.equals(asnOrderDTO, null)) {
            throw new Exception("车架号不正确，请确认是否有此车架号：" + vin);
        }
        if (Objects.equals(asnOrderDTO.getInspectStatus(), TmsInspectStatusEnum.WAYBILL_INIT.getValue())) {
            throw new BusinessException("此车架号" + vin + "未进行验车!");
        }
        if (Objects.equals(asnOrderDTO.getInspectStatus(), TmsInspectStatusEnum.WAYBILL_EXCP.getValue())) {
            throw new BusinessException("此车架号" + vin + "还未进行验车登记和移车申请");
        }
        if (Objects.equals(asnOrderDTO.getOdSupplierId(), null)) {
            throw new BusinessException("此车架号" + vin + "还未进行移车申请!");
        } else if (asnOrderDTO.getOdStatus().equals(String.valueOf(WmsInboundStatusEnum.WMS_INBOUND_WAIT_INBOUND.getValue()))) {
            throw new Exception("此车架号" + vin + "已收货，不允许再次收货");
        } else if (asnOrderDTO.getOdStatus().equals(String.valueOf(WmsInboundStatusEnum.WMS_INBOUND_FINISH.getValue()))) {
            throw new Exception("此车架号" + vin + "已入库，不允许再次收货");
        }

        //通过找到仓库code

        SysUserRoleExample sysUserRoleExample = new SysUserRoleExample();
        sysUserRoleExample.createCriteria().andUserIdEqualTo(userId);
        List<SysUserRole> sysUserRole = sysUserRoleMapper.selectByExample(sysUserRoleExample);

        WmsWarehouse wmsWarehouse = wmsWarehouseMapper.selectByPrimaryKey(sysUserRole.get(0).getWarehouseId());
        //List<WmsInboundPloy> wmsInboundPloyList = wmsInboundPloyExtMapper.getPloyList(wmsWarehouse.getWhCode());
        //根据策略code查询策略条件
        //查询所有空库位
        Map<String, Object> queryMap = Maps.newHashMap();
        Map<String, List<WmsEmptyLocationDTO>> zoneMap = Maps.newHashMap();//根据库区维度进行存放
        queryMap.put("whCode", wmsWarehouse.getWhCode());
        queryMap.put("locSize", locSize);
        List<WmsEmptyLocationDTO> locationList = wmsLocationExtMapper.getWmsEmptyLocation(queryMap);
        if (CollectionUtils.isEmpty(locationList) && locationList.size() <= 0) {
            throw new Exception("仓库没有了空库位，请联系IT人员。");
        }
        //
        //if (CollectionUtils.isNotEmpty(locationList) && locationList.size() > 0) {
        //    for (WmsEmptyLocationDTO wmsEmptyLocationDTO : locationList) {
        //        if (zoneMap.containsKey(wmsEmptyLocationDTO.getLocZoneCode())) {
        //            List<WmsEmptyLocationDTO> zlist = zoneMap.get(wmsEmptyLocationDTO.getLocZoneCode());
        //            zlist.add(wmsEmptyLocationDTO);
        //            zoneMap.put(wmsEmptyLocationDTO.getLocZoneCode(), zlist);
        //        } else {
        //            List<WmsEmptyLocationDTO> userList = Lists.newArrayList();
        //            userList.add(wmsEmptyLocationDTO);
        //            zoneMap.put(wmsEmptyLocationDTO.getLocZoneCode(), userList);
        //        }
        //    }
        //}
        //
        ///*Map<String,Map<String,Map<String,Object>>> map = Maps.newConcurrentMap();//所有策略信息
        //Map<String,Object> conditionMap = Maps.newConcurrentMap();//条件
        //Map<String,Object> flowtoMap = Maps.newConcurrentMap();//流向
        //Map<Long,Object> locationMap = Maps.newConcurrentMap();//库区库位*/
        //
        ////查询库区库位
        //
        //Map<String, List<WmsEmptyLocationDTO>> havaLocation = Maps.newHashMap();//得到空库位
        //if (wmsInboundPloyList.size() > 0) {
        //    List<WmsInboundPloyLocation> wmsInboundPloyLocationList = wmsInboundPloyLocationExtMapper.getPloyLocationList(wmsInboundPloyList.get(0).getPyCode());
        //    if (wmsInboundPloyLocationList.size() > 0) {
        //        for (WmsInboundPloyLocation wmsInboundPloyLocation : wmsInboundPloyLocationList) {
        //            String startRow = wmsInboundPloyLocation.getPylStartRow();//开始排
        //            String endRow = wmsInboundPloyLocation.getPylEndRow();//结束排
        //            List<WmsEmptyLocationDTO> list = zoneMap.get(wmsInboundPloyLocation.getPylZoneCode());//根据策略库区得到空库位
        //            List<WmsEmptyLocationDTO> getLocationListStr = getLoationList(list, Long.valueOf(startRow), Long.valueOf(endRow));
        //            havaLocation.put(wmsInboundPloyLocation.getPylZoneCode(), getLocationListStr);
        //        }
        //    }
        //}
        //
        ////已经被占用的库位，在第二次循环的时候需要去掉此list的库位。
        //
        //List<String> occupyList = Lists.newArrayList();
        //
        //
        ////循环被自动分配的订单
        //
        //
        ////for(WmsAllocationBO wmsAllocationBO : wmsAllocationVOList) {
        //String customerCode = asnOrderDTO.getOdCustomerCode();//货主
        //String vehicleSpecCode = asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddVehicleSpecCode();//车型
        //WmsInboundOrder wmsInboundOrder = wmsInboundOrderMapper.selectByPrimaryKey(asnOrderDTO.getOdId());
        //if (null == wmsInboundOrder) {
        //    Exception ex = new Exception("订单信息为空");
        //    throw ex;
        //}
        //String dest = wmsInboundOrder.getOdDest();//目的地
        //String origin = wmsInboundOrder.getOdOrigin();//起始地
        //
        ////订单能匹配上当前选择的策略，当订单匹配策略那么返回havaLocation里的库位，否则不返回让前端自己人工选择。
        //
        //boolean inPloy = true;
        //
        //
        ////查询条件
        //
        //if (wmsInboundPloyList.size() > 0) {
        //    List<WmsInboundPloyCondition> wmsInboundPloyConditionList = wmsInboundPloyConditionExtMapper.getPloyConditionList(wmsInboundPloyList.get(0).getPyCode());
        //    if (CollectionUtils.isNotEmpty(wmsInboundPloyConditionList) && wmsInboundPloyConditionList.size() > 0) {
        //        for (WmsInboundPloyCondition wmsInboundPloyCondition : wmsInboundPloyConditionList) {
        //            List<WmsInboundPloyOperator> wmsInboundPloyOperator = wmsInboundPloyOperatorExtMapper.getOperatorByCode(wmsInboundPloyCondition.getPycOperatorCode());
        //            String operatorCode = wmsInboundPloyOperator.get(0).getPyoOperatorCode();
        //            String[] value = wmsInboundPloyCondition.getPycValue().split("&");
        //
        //            if ("10".equals(wmsInboundPloyCondition.getPycType())) {//货主
        //                boolean flag = Arrays.asList(value).contains(customerCode);
        //
        //                //10为货主，判断订单是否适用于当前策略 ，不适用直接退出循环 库区库位赋值为空
        //
        //                if (!isPloy(operatorCode, flag)) {
        //                    asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhZoneCode("");
        //                    asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhLocCode("");
        //                    asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhZoneName("");
        //                    asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhLocName("");
        //                    break;
        //                }
        //            }
        //            if ("20".equals(wmsInboundPloyCondition.getPycType())) {//车型
        //
        //                //20为车型，判断订单是否适用于当前策略 ，不适用直接退出循环 库区库位赋值为空
        //
        //                if (!isPloy(operatorCode, Arrays.asList(value).contains(vehicleSpecCode))) {
        //                    asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhZoneCode("");
        //                    asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhZoneName("");
        //                    asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhLocName("");
        //                    asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhLocCode("");
        //                    break;
        //                }
        //            }
        //            //conditionMap.put(wmsInboundPloyCondition.getPycCode(), wmsInboundPloyCondition);
        //        }
        //    }
        //
        //
        //    //查询流向
        //
        //    List<WmsInboundPloyFlowto> wmsInboundPloyFlowtoList = wmsInboundPloyFlowtoExtMapper.getPloyFlowtoList(wmsInboundPloyList.get(0).getPyCode());
        //    if (CollectionUtils.isNotEmpty(wmsInboundPloyFlowtoList) && wmsInboundPloyFlowtoList.size() > 0) {
        //        for (WmsInboundPloyFlowto wmsInboundPloyFlowto : wmsInboundPloyFlowtoList) {
        //            if (wmsInboundPloyFlowto.getPyfFromCode().equals(origin) && wmsInboundPloyFlowto.getPyfToCode().equals(dest)) {
        //                inPloy = true;
        //            }
        //        }
        //    }
        //
        //    for (Map.Entry<String, List<WmsEmptyLocationDTO>> entry : havaLocation.entrySet()) {
        //        List<WmsEmptyLocationDTO> valueList = entry.getValue();
        //        if (CollectionUtils.isEmpty(valueList)) {
        //            break;
        //        }
        //        asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhZoneCode(entry.getKey());//code跟name一样
        //        asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhZoneName(entry.getKey());//code跟name一样
        //        for (WmsEmptyLocationDTO list : valueList) {
        //            asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhCode(list.getLocWhCode());
        //            asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhName(list.getLocWhName());
        //            asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhZoneCode(list.getLocZoneCode());
        //            asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhZoneName(list.getLocZoneName());
        //            asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhLocName(list.getLocName());
        //            asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhLocCode(list.getLocCode());
        //            occupyList.add(list.getLocCode());
        //            valueList.remove(list);
        //            break;
        //        }
        //    }
        //}

        //当策略没有匹配到库位那么任务分配一个库区库位

        if (StringUtils.isBlank(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhZoneCode())
                || StringUtils.isBlank(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhZoneCode())
                || StringUtils.isBlank(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhLocCode())
                || StringUtils.isBlank(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhLocName())) {
            asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhZoneCode(locationList.get(0).getLocZoneCode() == null ? locationList.get(0).getLocZoneName() : locationList.get(0).getLocZoneCode());
            asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhLocCode(locationList.get(0).getLocCode() == null ? locationList.get(0).getLocName() : locationList.get(0).getLocCode());
            asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhZoneName(locationList.get(0).getLocZoneName() == null ? locationList.get(0).getLocZoneCode() : locationList.get(0).getLocZoneName());
            asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhLocName(locationList.get(0).getLocName() == null ? locationList.get(0).getLocCode() : locationList.get(0).getLocName());
        }

        //修改入库单为已收货待入库

        WmsInboundOrder object = new WmsInboundOrder();
        object.setOdStatus(String.valueOf(WmsInboundStatusEnum.WMS_INBOUND_WAIT_INBOUND.getValue()));
        //查询用户，增加收货人字段
        SysUser sysUser = sysUserMapper.selectByPrimaryKey(userId);
        object.setOdConsigneeId(userId_str);
        object.setOdConsigneeDate(new Date());
        object.setOdConsigneeName(sysUser.getName());
        WmsInboundOrderExample wmsInboundOrderExample = new WmsInboundOrderExample();
        wmsInboundOrderExample.createCriteria().andOdIdEqualTo(asnOrderDTO.getOdId());
        wmsInboundOrderMapper.updateByExampleSelective(object, wmsInboundOrderExample);


        //更新order详情表

        String whCode = asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhCode();
        WmsInboundOrderDetail wmsInboundOrderDetail = new WmsInboundOrderDetail();
        wmsInboundOrderDetail.setOddOdId(asnOrderDTO.getOdId());
        //wmsInboundOrderDetail.setOddWhCode(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhCode());
        wmsInboundOrderDetail.setOddWhCode(whCode);
        wmsInboundOrderDetail.setOddWhName(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhName());
        wmsInboundOrderDetail.setOddWhZoneCode(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhZoneCode());
        wmsInboundOrderDetail.setOddWhZoneName(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhZoneName());
        wmsInboundOrderDetail.setOddWhLocCode(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhLocCode());
        wmsInboundOrderDetail.setOddWhLocName(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhLocName());
        WmsInboundOrderDetailExample wmsInboundOrderDetailExample = new WmsInboundOrderDetailExample();
        wmsInboundOrderDetailExample.createCriteria().andOddOdIdEqualTo(asnOrderDTO.getOdId());
        wmsInboundOrderDetailMapper.updateByExampleSelective(wmsInboundOrderDetail, wmsInboundOrderDetailExample);
        //插入新的 --手动事务 防止外层事务未进行提交 而重复插入
        //DefaultTransactionDefinition dtd = new DefaultTransactionDefinition();
        //dtd.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);// 事物隔离级别，开启新事务
        //TransactionStatus status = dataSourceTransactionManager.getTransaction(dtd); // 获得事务状态
        // 库区库位信息新增到分配表
        WmsInboundAllocation wmsInboundAllocation = new WmsInboundAllocation();
        wmsInboundAllocation.setAlVin(vin);
        wmsInboundAllocation.setAlStatus(WmsInboundAllocationStatusEnum.ALLOCATED_CONFIRM.getValue());
        wmsInboundAllocation.setAlWhId(String.valueOf(wmsWarehouse.getWhId()));
        wmsInboundAllocation.setAlSourceZoneCode(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhZoneCode());
        wmsInboundAllocation.setAlSourceZoneName(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhZoneName());
        wmsInboundAllocation.setAlSourceLocCode(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhLocCode());
        wmsInboundAllocation.setCreateUserId(String.valueOf(sysUser.getId()));
        wmsInboundAllocation.setAlSourceLocName(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhLocName());
        wmsInboundAllocation.setCreateUserName(sysUser.getName());
        wmsInboundAllocation.setIsDeleted(DeleteFlagEnum.NORMAL.getValue());
        wmsInboundAllocation.setGmtCreate(new Date());
        wmsInboundAllocation.setIsDeleted((byte) 1);
        //新增插入库位Id
        WmsLocationExample locationExample = new WmsLocationExample();
        locationExample.createCriteria()
                .andLocCodeEqualTo(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhLocCode())
                .andLocZoneCodeEqualTo(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhZoneCode())
                .andIsDeletedNotEqualTo(DeleteFlagEnum.DELETED.getValue());
        List<WmsLocation> wmsLocations = wmsLocationMapper.selectByExample(locationExample);
        if (CollectionUtils.isNotEmpty(wmsLocations)) {
            if (!Objects.equals(wmsLocations.get(0).getLocId(), null)) {
                wmsInboundAllocation.setAlSourceLocId(String.valueOf(wmsLocations.get(0).getLocId()));
            }
        }
        //使用存储过程 去重
        wmsInboundAllocationExtMapper.insertWmsAllocationByProcedure(wmsInboundAllocation);
        //极光推送库位信息,打印二维码
        //bugfix  修复页面打印二维码出错
        wmsLocationService.updateSendToAPPAndPrintCode(asnOrderDTO, userId_str);
        //bugfix 调用TMS接口入库数据传送
        try {
            sendInboundToTMSAndLog(sysUser, asnOrderDTO);
        } catch (BusinessException e) {
            LOGGER.error("WmsExtraInboundController.BusinessException error:", e);
            throw new BusinessException("调用TMS 失败:" + e.getMessage());
        } catch (Exception e) {
            LOGGER.error("WmsExtraInboundController.sendInboundToTMS error:", e);
            throw new BusinessException("调用TMS 接口异常");
        }
        return asnOrderDTO;
    }

    /**
     * 同步入库数据到TMS 和记录日志
     *
     * @param sysUser          用户
     * @param finalAsnOrderDTO dto
     */
    private void sendInboundToTMSAndLog(SysUser sysUser, AsnOrderDTO finalAsnOrderDTO) {
        String dt_inware, type = "";
        Integer inspectStatus = finalAsnOrderDTO.getInspectStatus();
        if (Objects.equals(inspectStatus, TmsInspectStatusEnum.WAYBILL_INIT.getValue())) {
            throw new BusinessException("该车辆还未验车!");
        }
        if (Objects.equals(inspectStatus, TmsInspectStatusEnum.WAYBILL_QUALIFY.getValue())) {
            type = INBOUND_QUALITY;//1
        }
        if (Objects.equals(inspectStatus, TmsInspectStatusEnum.WAYBILL_CONFIRM_EXCP.getValue())) {
            type = INBOUND_EXCP;//2
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dt_inware = sdf.format(new Date());
        AsnOrderDetailDTO detailDTO = finalAsnOrderDTO.getAsnOrderDetailDTOList().get(0);
        String locCode = StringUtils.isBlank(detailDTO.getOddWhLocName()) ? detailDTO.getOddWhLocCode() : detailDTO.getOddWhLocName();
        String result = inboundConfirmToTms(detailDTO.getOddVin(),
                //bugfix 2018/1/9 之前数据都是传的客户订单号字段值
                finalAsnOrderDTO.getOdWaybillNo(),
                dt_inware,
                sysUser.getName(),
                detailDTO.getOddWhName(),
                locCode,
                type);
        JSONObject jObject = JSON.parseObject(result);
        Boolean success = jObject.getBoolean("success");
        if (!success) {
            String message = jObject.getString("message");
            LOGGER.error("WmsExtraInboundController.sendInboundToTMS error:", message);
            throw new BusinessException("入库同步TMS失败:" + message);
        }
        String finalDt_inware = dt_inware;
        String finalType = type;
        Thread logThread = new Thread(() -> {
            //记录日志
            WmsTmsLogWithBLOBs tmsLog = new WmsTmsLogWithBLOBs();
            tmsLog.setGmtCreate(new Date());
            tmsLog.setGmtUpdate(new Date());
            tmsLog.setSendType(WmsGateControllerTypeEnum.GATE_OUT.getCode());
            tmsLog.setUrl("WmsExtraInboundController.sendInboundToTMS");
            tmsLog.setParam("{" +
                    "vin:" + detailDTO.getOddVin() + "," +
                    "waybill:" + finalAsnOrderDTO.getOdWaybillNo() + "," +
                    "dt_inware:" + finalDt_inware + "," +
                    "user:" + sysUser.getName() + "," +
                    "whCode:" + detailDTO.getOddWhName() + "," +
                    "locCode:" + locCode + "," +
                    "type:" + finalType + "," +
                    "}");
            tmsLog.setBody(result);
            tmsLog.setHead("sendInboundToTMS");
            wmsTmsLogMapper.insertSelective(tmsLog);
        });
        logThread.start();
    }


    /**
     * 调用 tms 的接口 入库确认
     *
     * @param vin        货物底盘号
     * @param custshipno 客户运单号
     * @param dt_inware  入库时间,yyyy-MM-dd hh24:mi:ss
     * @param userno     入库确认人
     * @param warehouse  入库仓库
     * @param pos        库位
     * @param type       入库类型，1.正常入库 ；2.异常入库
     */
    private String inboundConfirmToTms(String vin, String custshipno, String dt_inware, String userno, String warehouse, String pos, String type) {
        // 构建URL
        String url = propertyUrl;
        Integer time = Integer.parseInt(propertyTime);
        String encode_key = propertyKey;
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> headerMap = new HashMap<>();
        headerMap.put("encode-key", encode_key);
        url = url + "/mInware.jspx";
        map.put("vin", vin);
        map.put("custshipno", custshipno);
        map.put("dt_inware", dt_inware);
        map.put("userno", userno);
        map.put("warehouse", warehouse);
        map.put("pos", pos);
        map.put("type", type);
        String result;
        try {
            result = HttpRequestUtil.sendHttpPost(url, headerMap, map, time);
        } catch (Exception e) {
            throw new BusinessException("访问tms接口失败");
        }
        return result;
    }


    /**
     * 收货质检 - 君马
     *
     * @param vin        车架号
     * @param userId_str 用户id
     * @return 返回值
     */
    @Override
    public AsnOrderDTO saveAllcationByExtraForJunMa(String vin, String userId_str) {
        LOGGER.info("WmsStrategyServiceImpl.saveAllcationByExtraForJunMa vin: {}, userId: {}", vin, userId_str);
        AsnOrderDTO asnOrderDTO;
        try {
            //因为分为手动输入和扫码输入;需要根据长度判断是否输入的车架号
            if (StringUtils.isBlank(vin)) {
                throw new BusinessException("输入信息不能为空!");
            }
            if (StringUtils.isBlank(userId_str)) {
                throw new BusinessException("用户ID不能为空!");
            }
            int userId = Integer.parseInt(userId_str);

            //判断手动输入的是车架号还是卡号
            if (vin.trim().length() != 17) {
                //如果是卡号需要去关联卡和司机的绑定表
                WmsCardExample wmsCardExample = new WmsCardExample();
                wmsCardExample.setOrderByClause(" id desc ");
                int normal = DeleteFlagEnum.NORMAL.getValue();
                wmsCardExample.createCriteria()
                        .andCardNumEqualTo(vin)
                        .andStatusEqualTo(CarEnableEnum.USABLE.getCode())
                        .andIsDeleteEqualTo(normal);
                List<WmsCard> wmsCardList = wmsCardMapper.selectByExample(wmsCardExample);
                if (CollectionUtils.isEmpty(wmsCardList)) {
                    throw new BusinessException("未找到对应的绑定移库司机, 请核实");
                }

                WmsCard wmsCard = wmsCardList.get(0);
                if (wmsCard == null || wmsCard.getDriverId() == null) {
                    throw new BusinessException("该卡未绑定司机, 请核实");
                }
                asnOrderDTO = wmsInboundAsnOrderAddMapper.queryByDriverId(wmsCard.getDriverId());
                List<AsnOrderDetailDTO> asnOrderDetailDTOList = asnOrderDTO.getAsnOrderDetailDTOList();
                if (CollectionUtils.isNotEmpty(asnOrderDetailDTOList)) {
                    AsnOrderDetailDTO asnOrderDetailDTO = asnOrderDetailDTOList.get(0);
                    if (asnOrderDetailDTO != null) {
                        vin = asnOrderDetailDTO.getOddVin();
                    }
                }
            } else {
                // 通过vin得到入库基本信息
                asnOrderDTO = wmsInboundAsnOrderAddMapper.queryByVin(vin);
            }

            //校验
            if (Objects.equals(asnOrderDTO, null)) {
                throw new BusinessException("车架号/卡号不正确，请确认是否有此车架号/卡号：" + vin);
            }
            if (Objects.equals(asnOrderDTO.getInspectStatus(), TmsInspectStatusEnum.WAYBILL_INIT.getValue())) {
                throw new BusinessException("此车架号/卡号" + vin + "未进行验车!");
            }
            if (Objects.equals(asnOrderDTO.getInspectStatus(), TmsInspectStatusEnum.WAYBILL_EXCP.getValue())) {
                throw new BusinessException("此车架号/卡号" + vin + "还未进行验车登记和移车申请");
            }
            if (Objects.equals(asnOrderDTO.getOdSupplierId(), null)) {
                throw new BusinessException("此车架号/卡号" + vin + "还未进行移车申请!");
            } else if (asnOrderDTO.getOdStatus().equals(String.valueOf(WmsInboundStatusEnum.WMS_INBOUND_WAIT_INBOUND.getValue()))) {
                throw new BusinessException("此车架号/卡号" + vin + "已收货，不允许再次收货");
            } else if (asnOrderDTO.getOdStatus().equals(String.valueOf(WmsInboundStatusEnum.WMS_INBOUND_FINISH.getValue()))) {
                throw new BusinessException("此车架号/卡号" + vin + "已入库，不允许再次收货");
            }
            //
            // 通过找到仓库code
            //
            SysUserRoleExample sysUserRoleExample = new SysUserRoleExample();
            sysUserRoleExample.createCriteria().andUserIdEqualTo(userId);
            List<SysUserRole> sysUserRole = sysUserRoleMapper.selectByExample(sysUserRoleExample);

            WmsWarehouse wmsWarehouse = wmsWarehouseMapper.selectByPrimaryKey(sysUserRole.get(0).getWarehouseId());
            List<WmsInboundPloy> wmsInboundPloyList = wmsInboundPloyExtMapper.getPloyList(wmsWarehouse.getWhCode());
            //根据策略code查询策略条件

            //查询所有空库位
            Map<String, Object> queryMap = Maps.newHashMap();
            Map<String, List<WmsEmptyLocationDTO>> zoneMap = Maps.newHashMap();//根据库区维度进行存放
            queryMap.put("whCode", wmsWarehouse.getWhCode());
            List<WmsEmptyLocationDTO> locationList = wmsLocationExtMapper.getWmsEmptyLocation(queryMap);
            if (CollectionUtils.isEmpty(locationList) && locationList.size() <= 0) {
                throw new BusinessException("仓库没有了空库位，请联系IT人员。");
            }

            //if (CollectionUtils.isNotEmpty(locationList) && locationList.size() > 0) {
            //    for (WmsEmptyLocationDTO wmsEmptyLocationDTO : locationList) {
            //        if (zoneMap.containsKey(wmsEmptyLocationDTO.getLocZoneCode())) {
            //            List<WmsEmptyLocationDTO> zlist = zoneMap.get(wmsEmptyLocationDTO.getLocZoneCode());
            //            zlist.add(wmsEmptyLocationDTO);
            //            zoneMap.put(wmsEmptyLocationDTO.getLocZoneCode(), zlist);
            //        } else {
            //            List<WmsEmptyLocationDTO> userList = Lists.newArrayList();
            //            userList.add(wmsEmptyLocationDTO);
            //            zoneMap.put(wmsEmptyLocationDTO.getLocZoneCode(), userList);
            //        }
            //    }
            //}
            //// 查询库区库位
            //Map<String, List<WmsEmptyLocationDTO>> havaLocation = Maps.newHashMap();//得到空库位
            //if (wmsInboundPloyList.size() > 0) {
            //    List<WmsInboundPloyLocation> wmsInboundPloyLocationList = wmsInboundPloyLocationExtMapper.getPloyLocationList(wmsInboundPloyList.get(0).getPyCode());
            //    if (wmsInboundPloyLocationList.size() > 0) {
            //        for (WmsInboundPloyLocation wmsInboundPloyLocation : wmsInboundPloyLocationList) {
            //            String startRow = wmsInboundPloyLocation.getPylStartRow();//开始排
            //            String endRow = wmsInboundPloyLocation.getPylEndRow();//结束排
            //            List<WmsEmptyLocationDTO> list = zoneMap.get(wmsInboundPloyLocation.getPylZoneCode());//根据策略库区得到空库位
            //            List<WmsEmptyLocationDTO> getLocationListStr = getLoationList(list, Long.valueOf(startRow), Long.valueOf(endRow));
            //            havaLocation.put(wmsInboundPloyLocation.getPylZoneCode(), getLocationListStr);
            //        }
            //    }
            //}
            //// 已经被占用的库位，在第二次循环的时候需要去掉此list的库位。
            //List<String> occupyList = Lists.newArrayList();
            //
            //// 循环被自动分配的订单
            //String customerCode = asnOrderDTO.getOdCustomerCode();//货主
            //String vehicleSpecCode = asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddVehicleSpecCode();//车型
            //WmsInboundOrder wmsInboundOrder = wmsInboundOrderMapper.selectByPrimaryKey(asnOrderDTO.getOdId());
            //if (null == wmsInboundOrder) {
            //    throw new BusinessException("订单信息为空");
            //}
            //String dest = wmsInboundOrder.getOdDest();//目的地
            //String origin = wmsInboundOrder.getOdOrigin();//起始地
            //// 订单能匹配上当前选择的策略，当订单匹配策略那么返回havaLocation里的库位，否则不返回让前端自己人工选择。
            //boolean inPloy = true;
            //
            //// 查询条件
            //if (wmsInboundPloyList.size() > 0) {
            //    List<WmsInboundPloyCondition> wmsInboundPloyConditionList = wmsInboundPloyConditionExtMapper.getPloyConditionList(wmsInboundPloyList.get(0).getPyCode());
            //    if (CollectionUtils.isNotEmpty(wmsInboundPloyConditionList) && wmsInboundPloyConditionList.size() > 0) {
            //        for (WmsInboundPloyCondition wmsInboundPloyCondition : wmsInboundPloyConditionList) {
            //            List<WmsInboundPloyOperator> wmsInboundPloyOperator = wmsInboundPloyOperatorExtMapper.getOperatorByCode(wmsInboundPloyCondition.getPycOperatorCode());
            //            String operatorCode = wmsInboundPloyOperator.get(0).getPyoOperatorCode();
            //            String[] value = wmsInboundPloyCondition.getPycValue().split("&");
            //
            //            if ("10".equals(wmsInboundPloyCondition.getPycType())) {//货主
            //                boolean flag = Arrays.asList(value).contains(customerCode);
            //                //
            //                // 10为货主，判断订单是否适用于当前策略 ，不适用直接退出循环 库区库位赋值为空
            //                //
            //                if (!isPloy(operatorCode, flag)) {
            //                    asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhZoneCode("");
            //                    asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhZoneName("");
            //                    asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhLocName("");
            //                    asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhLocCode("");
            //                    break;
            //                }
            //            }
            //            if ("20".equals(wmsInboundPloyCondition.getPycType())) {//车型
            //                //
            //                //20为车型，判断订单是否适用于当前策略 ，不适用直接退出循环 库区库位赋值为空
            //                //
            //                if (!isPloy(operatorCode, Arrays.asList(value).contains(vehicleSpecCode))) {
            //                    asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhZoneCode("");
            //                    asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhLocCode("");
            //                    asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhZoneName("");
            //                    asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhLocName("");
            //                    break;
            //                }
            //            }
            //        }
            //    }
            //
            //
            //    //查询流向
            //
            //    List<WmsInboundPloyFlowto> wmsInboundPloyFlowtoList = wmsInboundPloyFlowtoExtMapper.getPloyFlowtoList(wmsInboundPloyList.get(0).getPyCode());
            //    if (CollectionUtils.isNotEmpty(wmsInboundPloyFlowtoList) && wmsInboundPloyFlowtoList.size() > 0) {
            //        for (WmsInboundPloyFlowto wmsInboundPloyFlowto : wmsInboundPloyFlowtoList) {
            //            if (wmsInboundPloyFlowto.getPyfFromCode().equals(origin) && wmsInboundPloyFlowto.getPyfToCode().equals(dest)) {
            //                inPloy = true;
            //            }
            //        }
            //    }
            //
            //    for (Map.Entry<String, List<WmsEmptyLocationDTO>> entry : havaLocation.entrySet()) {
            //        List<WmsEmptyLocationDTO> valueList = entry.getValue();
            //        if (CollectionUtils.isEmpty(valueList)) {
            //            break;
            //        }
            //        asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhZoneCode(entry.getKey());//code跟name一样
            //        asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhZoneName(entry.getKey());//code跟name一样
            //        for (WmsEmptyLocationDTO list : valueList) {
            //            asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhCode(list.getLocWhCode());
            //            asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhName(list.getLocWhName());
            //            asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhZoneName(list.getLocZoneName());
            //            asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhZoneCode(list.getLocZoneCode());
            //            asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhLocCode(list.getLocCode());
            //            asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhLocName(list.getLocName());
            //            occupyList.add(list.getLocCode());
            //            valueList.remove(list);
            //            break;
            //        }
            //    }
            //}


            //当策略没有匹配到库位那么任务分配一个库区库位

            if (StringUtils.isBlank(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhZoneCode())
                    || StringUtils.isBlank(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhZoneCode())
                    || StringUtils.isBlank(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhLocCode())
                    || StringUtils.isBlank(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhLocName())) {
                asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhZoneCode(locationList.get(0).getLocZoneCode() == null ? locationList.get(0).getLocZoneName() : locationList.get(0).getLocZoneCode());
                asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhZoneName(locationList.get(0).getLocZoneName() == null ? locationList.get(0).getLocZoneCode() : locationList.get(0).getLocZoneName());
                asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhLocCode(locationList.get(0).getLocCode() == null ? locationList.get(0).getLocName() : locationList.get(0).getLocCode());
                asnOrderDTO.getAsnOrderDetailDTOList().get(0).setOddWhLocName(locationList.get(0).getLocName() == null ? locationList.get(0).getLocCode() : locationList.get(0).getLocName());
            }


            //修改入库单为已收货待入库

            WmsInboundOrder object = new WmsInboundOrder();
            object.setOdStatus(String.valueOf(WmsInboundStatusEnum.WMS_INBOUND_WAIT_INBOUND.getValue()));
            //查询用户，增加收货人字段
            SysUser sysUser = sysUserMapper.selectByPrimaryKey(userId);
            object.setOdConsigneeId(userId_str);
            object.setOdConsigneeDate(new Date());
            object.setOdConsigneeName(sysUser.getName());
            WmsInboundOrderExample wmsInboundOrderExample = new WmsInboundOrderExample();
            wmsInboundOrderExample.createCriteria().andOdIdEqualTo(asnOrderDTO.getOdId());
            wmsInboundOrderMapper.updateByExampleSelective(object, wmsInboundOrderExample);


            //更新order详情表

            String whCode = asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhCode();
            WmsInboundOrderDetail wmsInboundOrderDetail = new WmsInboundOrderDetail();
            wmsInboundOrderDetail.setOddOdId(asnOrderDTO.getOdId());
            //wmsInboundOrderDetail.setOddWhCode(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhCode());
            wmsInboundOrderDetail.setOddWhCode(whCode);
            wmsInboundOrderDetail.setOddWhName(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhName());
            wmsInboundOrderDetail.setOddWhZoneCode(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhZoneCode());
            wmsInboundOrderDetail.setOddWhZoneName(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhZoneName());
            wmsInboundOrderDetail.setOddWhLocCode(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhLocCode());
            wmsInboundOrderDetail.setOddWhLocName(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhLocName());
            WmsInboundOrderDetailExample wmsInboundOrderDetailExample = new WmsInboundOrderDetailExample();
            wmsInboundOrderDetailExample.createCriteria().andOddOdIdEqualTo(asnOrderDTO.getOdId());
            wmsInboundOrderDetailMapper.updateByExampleSelective(wmsInboundOrderDetail, wmsInboundOrderDetailExample);
            //调用存储过程
            // 库区库位信息新增到分配表
            WmsInboundAllocation wmsInboundAllocation = new WmsInboundAllocation();
            wmsInboundAllocation.setAlVin(vin);
            wmsInboundAllocation.setAlStatus(WmsInboundAllocationStatusEnum.ALLOCATED_CONFIRM.getValue());
            wmsInboundAllocation.setAlWhId(String.valueOf(wmsWarehouse.getWhId()));
            wmsInboundAllocation.setAlSourceZoneCode(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhZoneCode());
            wmsInboundAllocation.setAlSourceZoneName(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhZoneName());
            wmsInboundAllocation.setAlSourceLocCode(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhLocCode());
            wmsInboundAllocation.setAlSourceLocName(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhLocName());
            wmsInboundAllocation.setCreateUserId(String.valueOf(sysUser.getId()));
            wmsInboundAllocation.setCreateUserName(sysUser.getName());
            wmsInboundAllocation.setIsDeleted(DeleteFlagEnum.NORMAL.getValue());
            wmsInboundAllocation.setGmtCreate(new Date());
            wmsInboundAllocation.setGmtUpdate(new Date());
            wmsInboundAllocation.setIsDeleted((byte) 1);
            //新增插入库位Id
            WmsLocationExample locationExample = new WmsLocationExample();
            locationExample.createCriteria()
                    .andLocCodeEqualTo(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhLocCode())
                    .andLocZoneCodeEqualTo(asnOrderDTO.getAsnOrderDetailDTOList().get(0).getOddWhZoneCode())
                    .andIsDeletedNotEqualTo(DeleteFlagEnum.DELETED.getValue());
            List<WmsLocation> wmsLocations = wmsLocationMapper.selectByExample(locationExample);
            if (CollectionUtils.isNotEmpty(wmsLocations)) {
                if (!Objects.equals(wmsLocations.get(0).getLocId(), null)) {
                    wmsInboundAllocation.setAlSourceLocId(String.valueOf(wmsLocations.get(0).getLocId()));
                }
            }
            //使用存储过程 去重
            wmsInboundAllocationExtMapper.insertWmsAllocationByProcedure(wmsInboundAllocation);
        } catch (BusinessException e) {
            LOGGER.error("WmsStrategyServiceImpl.saveAllcationByExtraForJunMa BusinessException:", e);
            throw new BusinessException(e.getMessage());
        } catch (Exception e) {
            LOGGER.error("WmsStrategyServiceImpl.saveAllcationByExtraForJunMa error:", e);
            throw new BusinessException("分配库位异常!");
        }
        return asnOrderDTO;
    }

    @Override
    public void saveBarcodeKey(Long odId, String vin, String key) {
        WmsInboundOrder wmsInboundOrder = new WmsInboundOrder();
        wmsInboundOrder.setOdId(odId);
        wmsInboundOrderMapper.updateByPrimaryKeySelective(wmsInboundOrder);
    }
}